var pluginver = 1.79;
var apiState = false;
var moneydata = {};
var conf = { "经济类型": "", "货币名称": "money" };
var orread = false;
var state = false;
var playerlist = {};
var oldscore;

function exportinfo(type, a, b, c, d) {
    if (type == 'getmoney')
        return getmoney(a);
    if (type == 'setmoney')
        return setmoney(a, b);
    if (type == 'tranmoney')
        return tranmoney(a, b, c, d);
    if (type == 'moneytype')
        return conf.get("经济类型");
    if (type == 'version')
        return pluginver;
    if (type == 'moneyname')
        return conf.get("货币名称");
}

function ErrorMessage(err) {
    try {
        file.mkdir('.\\logs\\Error');
        colorLog('red', '[' + system.getTimeStr() + '][Economic_core][ERROR][' + pluginver + ']:');
        colorLog('red', 'name: ' + err.name + '');
        colorLog('red', 'errorNumber: ' + (err.number & 0xFFFF) + '');
        colorLog('red', 'message: ' + err.message + '');
        colorLog('red', 'stack: ' + err.stack + '');
        file.writeLine('.\\logs\\Error\\Economic_core_Error_stack.txt', '[' + system.getTimeStr() + '][Economic_core][ERROR][' + pluginver + ']:');
        file.writeLine('.\\logs\\Error\\Economic_core_Error_stack.txt', 'name: ' + err.name + '');
        file.writeLine('.\\logs\\Error\\Economic_core_Error_stack.txt', 'errorNumber: ' + (err.number & 0xFFFF) + '');
        file.writeLine('.\\logs\\Error\\Economic_core_Error_stack.txt', 'message: ' + err.message + '');
        file.writeLine('.\\logs\\Error\\Economic_core_Error_stack.txt', 'stack: ' + err.stack + '');
        colorLog('green', '错误堆栈信息已输出至.\\plugins\\logs\\Error\\Economic_core_Error_stack.txt,请将此文件发送至此插件开发者');
    } catch (_) {
        log('[Error]经济核心不支持此加载器!!!')
    }
}

function checkNumber(theObj) {
    try {
        if (typeof (JSON.parse(theObj)) == "number") {
            return true;
        }
        return false;
    } catch (_) {
        return false;
    }
}

function getNumber(val) {
    try {
        return JSON.parse(val);
    } catch (_) {
        return val;
    }
}

function ST(pl, text) {
    try {
        pl.tell('§l§d[MONEY] ' + text + '');
    } catch (e) {
        ErrorMessage(e)
    }
}

function moneypay(pl, cmd) {
    try {
        if (cmd.length == 2 && checkNumber(cmd[1])) {
            var player = cmd[0];
            var val = JSON.parse(cmd[1]);
            var plmon = getmoney(pl.realName);
            var playermon = getmoney(player);
            if (plmon != null && playermon != null) {
                if (plmon >= val) {
                    tranmoney(pl.realName, player, val, pl.realName + '转账');
                    ST(pl, `§b转账成功!剩余余额: §e${getmoney(pl.realName)} §f${conf.get("货币名称")}`);
                } else
                    ST(pl, '§c余额不足!剩余: §e' + plmon + ' §f' + conf.get("货币名称"));
            } else
                ST(pl, '§c对方的数据不存在!');
        } else
            ST(pl, '§c命令输入错误，请检查后重试');
    } catch (e) {
        ErrorMessage(e);
    }
}

function moneyadd(pl, cmd) {
    try {
        if (cmd.length == 2 && checkNumber(cmd[1])) {
            var player = cmd[0];
            var val = JSON.parse(cmd[1]);
            var playermon = getmoney(player);
            if (playermon != null && (playermon + val) > -1) {
                var sec = setmoney(player, playermon + val);
                if (sec == true)
                    ST(pl, `§a操作成功!TA现在拥有 §f${conf.get('货币名称')} §b为 §e${getmoney(player)}`);
                else
                    ST(pl, '§c操作失败!原因未知!');
            } else
                ST(pl, '操作失败,原因:玩家对象不存在或者得出货币为负数');
        } else
            ST(pl, '§b命令异常，请检查后重试');
    } catch (e) {
        ErrorMessage(e);
    }
}

function moneyreduce(pl, cmd) {
    try {
        if (cmd.length == 2 && checkNumber(cmd[1])) {
            moneyadd(pl, [cmd[0], -cmd[1]]);
        } else
            ST(pl, '命令异常,请检查后重试');
    } catch (e) {
        ErrorMessage(e);
    }
}

function moneyset(pl, cmd) {
    try {
        if (cmd.length == 2 && checkNumber(cmd[1])) {
            var player = cmd[0];
            var val = JSON.parse(cmd[1]);
            var playermon = getmoney(player);
            if (playermon != null && val > -1) {
                var sec = setmoney(player, val);
                if (sec == true)
                    ST(pl, `§a操作成功!TA现在拥有 §f${conf.get('货币名称')} §b为 §e${getmoney(player)}`);
                else
                    ST(pl, '§c操作失败!原因未知!');
            } else
                ST(pl, '§c操作失败,原因:玩家对象不存在或者设置的参数为负数');
        } else
            ST(pl, '§c命令输入错误,请检查后重试');
    } catch (e) {
        ErrorMessage(e);
    }
}

function moneyquery(pl, cmd) {
    try {
        if (cmd.length < 2) {
            if (cmd.length == 0)
                ST(pl, `§b你还剩余: §e${getmoney(pl.realName)} §f${conf.get("货币名称")}`);
            else {
                var moneyg = getmoney(cmd[0]);
                if (moneyg != null)
                    ST(pl, `§a玩家: §e${cmd[0]} §b还剩余: §e${moneyg} §f${conf.get("货币名称")}`);
                else
                    ST(pl, '§c该玩家对象不存在');
            }
        }
    } catch (e) {
        ErrorMessage(e);
    }
}

function moneygui(pl, cmd) {
    try {
        if (cmd.length == 0) {
            var butt = ["转账", "查看排行榜"];
            var image = ["", ""];
            if (pl.isOP()) {
                butt = ["转账", "查看排行榜", "OP快捷管理"];
                image = ["", "", ""];
            }
            pl.sendSimpleForm('§l§dMONEYGUI', '选择一个项:', butt, image, function (pl1, selected) {
                try {
                    if (selected != null) {
                        if (selected == 0) {
                            var newform = mc.newSimpleForm();
                            newform.setTitle('§l§dMONEYPAY');
                            newform.setContent("§l§a选择一个玩家进行转账\n§b您还剩余 §e" + getmoney(pl.realName) + " §f" + conf.get("货币名称") + "");
                            var olm = JSON.parse(moneydata.read());
                            var pllist = [];
                            for (var i in olm) {
                                var plname = data.xuid2name(i);
                                pllist.push({ "name": plname, "val": olm[i] });
                                newform.addButton(plname);
                            }
                            pl1.sendForm(newform, function (pl2, selected1) {
                                try {
                                    if (selected1 != null) {
                                        var newform1 = mc.newCustomForm();
                                        newform1.setTitle('§l§dMONEYPAY');
                                        newform1.addInput('§l§b向§e ' + pllist[selected1].name + ' §b转多少 §f' + conf.get("货币名称") + '\nTA还剩余 §e ' + pllist[selected1].val + ' §f' + conf.get("货币名称") + '', '请输入正数');
                                        pl2.sendForm(newform1, function (pl3, selected2) {
                                            try {
                                                if (selected2 != null) {
                                                    if (checkNumber(selected2[0]) && selected2[0] > 0) {
                                                        selected2[0] = getNumber(selected2[0]);
                                                        if (selected2[0] <= getmoney(pl3.realName)) {
                                                            var sec = tranmoney(pl3.realName, pllist[selected1].name, selected2[0], pl3.realName + '转账');
                                                            if (sec)
                                                                ST(pl3, `§b转账成功!剩余余额: §e${getmoney(pl3.realName)} §f${conf.get("货币名称")}`);
                                                            else
                                                                ST(pl3, '§c转账失败，原因未知');
                                                        } else
                                                            ST(pl, '§c余额不足!剩余: §e' + getmoney(pl3.realName) + ' §f' + conf.get("货币名称"));
                                                    } else
                                                        ST(pl3, '§c参数异常');
                                                } else
                                                    ST(pl3, '§b已放弃表单');
                                            } catch (e) {
                                                ErrorMessage(e);
                                            }
                                        })
                                    } else
                                        ST(pl2, '§b已放弃表单');
                                } catch (e) {
                                    ErrorMessage(e);
                                }
                            })
                        } else if (selected == 1) {
                            var newform = mc.newCustomForm();
                            newform.setTitle('§l§dRANKINGLIST')
                            var newArray = [];
                            var olm = JSON.parse(moneydata.read());
                            for (var i in olm) {
                                var name = data.xuid2name(i);
                                var mon = olm[i];
                                newArray.push({ "name": name, "val": mon });
                            }
                            newArray.sort(function (a, b) {
                                try {
                                    return b.val - a.val;
                                } catch (e) {
                                    ErrorMessage(e);
                                }
                            })
                            for (var i in newArray) {
                                var text = '§l§f名称: ' + newArray[i].name + '-----§f' + conf.get("货币名称") + ': §f' + newArray[i].val + '';
                                newform.addLabel(text);
                            }
                            pl1.sendForm(newform, function (pl2, selected1) { })
                        } else if (selected == 2 && pl1.isOP()) {
                            var newform = mc.newCustomForm();
                            newform.setTitle("§l§dMONEYADMINI");
                            var sel = [];
                            var plm = JSON.parse(moneydata.read());
                            for (var i in plm) {
                                sel.push(`${data.xuid2name(i)}-${plm[i]}`);
                            }
                            newform.addDropdown('§l§b选择一个玩家进行操作:', sel);
                            pl1.sendForm(newform, function (pl2, selected1) {
                                try {
                                    if (selected1 != null) {
                                        var select = sel[selected1[0]].split('-')[0];
                                        var mone = JSON.parse(sel[selected1[0]].split('-')[1]);
                                        var newform1 = mc.newCustomForm();
                                        newform1.setTitle("§l§dMONEYADMINI");
                                        newform1.addLabel(`§l§b当前选择玩家:§e ${select},§bTA的§f ${conf.get("货币名称")}为: §e ${mone}`);
                                        newform1.addSwitch('§l§a开启为添加(减少)模式,关闭为设置模式', true);
                                        newform1.addInput('添加(减少)模式可以输入正(负)数,设置模式请勿输入负数!', 'Number', '');
                                        pl2.sendForm(newform1, function (pl3, selected2) {
                                            try {
                                                if (selected2 != null) {
                                                    var mode = selected2[1];
                                                    var shu = selected2[2];
                                                    if (checkNumber(shu)) {
                                                        shu = getNumber(shu);
                                                        if (mode == true) {
                                                            var moneyin = getmoney(select);
                                                            setmoney(select, (moneyin + shu));
                                                            ST(pl3, '§a操作成功');
                                                        } else {
                                                            if (shu > -1) {
                                                                setmoney(select, shu);
                                                                ST(pl3, '§a操作成功');
                                                            } else
                                                                ST(pl3, '§c操作被拒绝!原因:输入的数字不可为负数!');
                                                        }
                                                    } else
                                                        ST(pl3, '§c操作被拒绝!原因:输入的类型不属于数字!');
                                                } else
                                                    ST(pl3, '§b表单已放弃');
                                            } catch (e) {
                                                ErrorMessage(e);
                                            }
                                        })
                                    } else
                                        ST(pl2, '§b表单已放弃');
                                } catch (e) {
                                    ErrorMessage(e);
                                }
                            })
                        }
                    } else
                        ST(pl1, '§b表单已放弃');
                } catch (e) {
                    ErrorMessage(e);
                }
            })
        } else
            return true;
    } catch (e) {
        ErrorMessage(e);
    }
}

function getmoney(name) {
    try {
        if (typeof (name) == "string") {
            var xuid = data.name2xuid(name);
            var pl = mc.getPlayer(xuid);
            if (pl != null) {
                if (conf.get("经济类型") == 'score') {
                    if (pl.getScore('money') == null)
                        pl.setScore('money', 0);
                    return pl.getScore("money");
                } else {
                    if (money.get(pl.xuid) == null)
                        money.set(pl.xuid, 0);
                    return money.get(pl.xuid);
                }
            } else {
                if (xuid != null) {
                    if (conf.get("经济类型") == 'score') {
                        if (moneydata.get(xuid) == null)
                            moneydata.set(xuid, 0);
                        return moneydata.get(xuid);
                    } else {
                        if (money.get(xuid) == null)
                            money.set(xuid, 0);
                        return money.get(xuid);
                    }
                } else
                    return null;
            }
        } else
            return null;
    } catch (e) {
        ErrorMessage(e);
        return null;
    }
}

function setmoney(name, val, type) {
    try {
        if (typeof (name) == "string" && checkNumber(val) && data.name2xuid(name) != null && data.name2xuid(name) != '') {
            var xuid = data.name2xuid(name);
            val = getNumber(val);
            if (val != moneydata.get(data.name2xuid(name)) || type == 'join') {
                var old = moneydata.get(xuid);
                var pl = mc.getPlayer(xuid);
                if (pl != null) {
                    moneydata.set(pl.xuid, val);
                    if (conf.get("经济类型") == 'score') {
                        var old1 = pl.getScore('money');
                        pl.setScore('money', val);
                        if (type != 'join')
                            ST(pl, `§b经济变动:您现在拥有: §e${getmoney(pl.realName)} §f${conf.get("货币名称")},§b变动值: ${val - old}`);
                        else
                            ST(pl, `§b经济变动:您现在拥有: §e${getmoney(pl.realName)} §f${conf.get("货币名称")},§b变动值: ${val - old1}`);
                        return true;
                    } else {
                        money.set(pl.xuid, val);
                        ST(pl, `§b经济变动:您现在拥有: §e${getmoney(pl.realName)} §f${conf.get("货币名称")},§b变动值: ${val - old}`);
                        return true;
                    }
                } else {
                    if (conf.get("经济类型") == 'score')
                        return moneydata.set(xuid, val);
                    else
                        return money.set(xuid, val);
                }
            } else
                return true;
        } else
            return null;
    } catch (e) {
        ErrorMessage(e);
        return null;
    }
}

function tranmoney(name, jname, val, note) {
    try {
        if (typeof (note) != "string") {
            note = '';
        }
        if (typeof (name) == "string" && typeof (jname) == "string" && typeof (val) == "number" && data.name2xuid(name) != null && data.name2xuid(jname) != null) {
            var pl1xuid = data.name2xuid(name);
            var pl2xuid = data.name2xuid(jname);
            if (conf.get("经济类型") == 'score') {
                var nmo = getmoney(name);
                var jmo = getmoney(jname);
                if (nmo >= val) {
                    setmoney(name, nmo - val);
                    setmoney(jname, jmo + val);
                    return true;
                }
            } else {
                var nmo = getmoney(name);
                var jmo = getmoney(jname);
                if (nmo >= val) {
                    moneydata.set(data.name2xuid(name), nmo - val);
                    moneydata.set(data.name2xuid(jname), jmo + val);
                    var pl1 = mc.getPlayer(pl1xuid);
                    var pl2 = mc.getPlayer(pl2xuid);
                    money.trans(pl1xuid, pl2xuid, val, note);
                    if (pl1 != null)
                        ST(pl1, `§b经济变动:您现在拥有: §e${getmoney(pl1.realName)} §f${conf.get("货币名称")},§b变动值: -${val}`);
                    if (pl2 != null)
                        ST(pl2, `§b经济变动:您现在拥有: §e${getmoney(pl2.realName)} §f${conf.get("货币名称")},§b变动值: ${val}`);
                    return true;
                }
            }
        } else
            return false;
    } catch (e) {
        ErrorMessage(e);
        return null;
    }
}

function join(pl) {
    try {
        if (conf.get("经济类型") == 'score') {
            pl.addScore('money', 0);
            if (moneydata.get(pl.xuid) == null)
                moneydata.set(pl.xuid, 0);
            if (getNumber(pl.getScore('money')) != getNumber(moneydata.get(pl.xuid))) {
                setmoney(pl.realName, moneydata.get(pl.xuid), 'join');
            }
        } else {
            money.add(pl.xuid, 0);
            if (moneydata.get(pl.xuid) != money.get(pl.xuid)) {
                var yy = money.get(pl.xuid);
                var old = moneydata.get(pl.xuid);
                if (yy != old) {
                    setmoney(pl.realName, yy, 'join');
                }
            }
        }
    } catch (e) {
        ErrorMessage(e);
    }
    playerlist[pl.realName] = true;
}

function left(pl) {
    if (playerlist[pl.realName])
        delete playerlist[pl.realName];
}

function scorechang(pl, num, name, disname) {
    try {
        var scorehh = `${pl.realName}-${num}-${disname}`;
        if (pl != null && name == 'money' && oldscore != scorehh && playerlist[pl.realName])
            setmoney(pl.realName, num);
        else
            oldscore = scorehh;
    } catch (e) {
        ErrorMessage(e);
    }
}

function llmoneychange() {
    try {
        var list = mc.getOnlinePlayers();
        for (var i in list) {
            var pl = list[i];
            if (money.get(pl.xuid) != moneydata.get(pl.xuid))
                setmoney(pl.realName, money.get(pl.xuid));
        }
    } catch (e) {
        ErrorMessage(e);
    }
}

function load() {
    try {
        mc.listen("onJoin", join);
        mc.listen("onLeft", left);
        mc.regPlayerCmd('money', '经济系统', moneygui, 0);
        mc.regPlayerCmd('money gui', '经济GUI', moneygui, 0);
        if (conf.get("经济类型") == "score") {
            mc.listen("onScoreChanged", scorechang);
            mc.regPlayerCmd('money pay', '/money pay <input:playername> <input:Num> 向某人转账', moneypay, 0);
            mc.regPlayerCmd('money add', '/money add <input:playername> <input:Num> 给某人添加经济', moneyadd, 1);
            mc.regPlayerCmd('money set', '/money set <input:playername> <input:Num> 设置某人的经济', moneyset, 1);
            mc.regPlayerCmd('money reduce', '/money reduce <input:playername> <input:Num> 扣除某人的经济', moneyreduce, 1)
            mc.regPlayerCmd('money query', '/money query [input:playername] 查询自己的经济或者别人的经济', moneyquery, 0);
            setTimeout(function () {
                var score = mc.getScoreObjective('money');
                if (score == null) {
                    mc.newScoreObjective('money', 'money');
                    log('[INFO][Economic_core] 检测到记分板不存在,已自动创建');
                }
            }, 3000)
        } else {
            setInterval(function () {
                llmoneychange();
            }, 3000);
        }
    } catch (e) {
        ErrorMessage(e);
    }
}

function read() {
    try {
        if (!orread) {
            conf = data.openConfig('.\\plugins\\Timiya\\config\\economic_core.json', 'json', JSON.stringify(conf));
            moneydata = data.openConfig('.\\plugins\\Timiya\\data\\offlineMoney.json', 'json', '{}');
            return true;
        } else {
            conf.reload();
            moneydata.reload();
            return true
        }
    } catch (e) {
        ErrorMessage(e);
        log('[' + system.getTimeStr() + ' INFO][Economic_core] 经济核心遇到了一个问题:JSON解析失败,可能解决的方式:更改配置文件编码');
        return false;
    }
}

function start() {
    try {
        if (read()) {
            orread = true;
            if (conf.get("经济类型") == "score" || conf.get("经济类型") == "llmoney") {
                log(`[INFO][Economic_core] 您可以输入ECupdate检查更新`);
                state = true;
                if (conf.get("开服自动检查更新", true)) {
                    conf.set("开服自动检查更新", true);
                    checkupdate();
                }
                load();
            } else {
                colorLog('yellow', '■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■');
                colorLog('yellow', '■');
                colorLog('yellow', '■    配置文件已输出,请手动配置Economic_core,否则Economic_core将不会工作');
                colorLog('yellow', '■    您可以在.plugins/Timiya/config目录找到economic_core.json');
                colorLog('yellow', '■    经济类型您可以选填 "score" 或 "llmoney",改完后输入ECreload进行重新加载');
                colorLog('yellow', '■    score(记分板模式) llmoney(LiteLoaderMoney模式)');
                colorLog('yellow', '■');
                colorLog('yellow', '■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■');
            }
        }
    } catch (e) {
        ErrorMessage(e);
    }
}

mc.listen("onServerStarted", start);
mc.regConsoleCmd('ECreload', '重新加载经济核心', function () {
    try {
        if (!state)
            start();
        else
            return true;
    } catch (e) {
        ErrorMessage(e);
    }
})

mc.regConsoleCmd('ECupdate', '检查Economic_core更新', function () {
    try {
        checkupdate();
    } catch (e) {
        ErrorMessage(e);
    }
})

function checkupdate() {
    log('[INFO][Economic_core] 开始检查更新...');
    network.httpGet('https://gitee.com/timidine/mcbe-lite-xloader-economic_core/raw/master/version.txt', function (a, b) {
        if (a == 200) {
            if (b != pluginver) {
                log('[INFO][Economic_core] 检测到更新包!更新包版本:' + b + '');
                log('[INFO][Economic_core] 开始下载...');
                network.httpGet('https://gitee.com/timidine/mcbe-lite-xloader-economic_core/raw/master/Economic_core.js', function (c, d) {
                    if (c == 200) {
                        file.writeTo('.\\plugins\\Economic_core.js', d.replace(/\r/g,''));
                        log('[INFO][Economic_core] 更新下载完成,开始更新插件...');
                        setTimeout(function () {
                            mc.runcmd('lxl unload Economic_core.js');
                            mc.runcmd('lxl load plugins/Economic_core.js');
                        }, 1000)
                    } else
                        log('[INFO][Economic_core] 下载失败!返回值:' + c + '');
                })
            } else
                log('[INFO][Economic_core] 已是最新版本:' + pluginver + '');
        } else
            log('[INFO][Economic_core] 获取更新失败!返回值:' + a + '');
    })
}

apiState = lxl.export(exportinfo, 'MONEY');
if (apiState)
    log('[INFO][Economic_core] API导出成功');
else
    log('[INFO][Economic_core] API导出失败');